#include <iostream>
#include <vector>
#include <unistd.h>
#include "Task.hpp"

 std::vector<task_t> tasks;
class channel
{
public:
    channel(int wfd, pid_t pid)
        : _wfd(wfd), _pid(pid)
    {
    }

    bool send(int cmdcode)
    {
        int n = write(_wfd, &cmdcode, sizeof(int));
        std::cout << "write-n:" << n << std::endl;
        if (n < 0)
        {
            perror("write");
            return false;
        }
        return true;
    }

private:
    int _wfd; // 父进程写的文件描述符
    int _pid;
};

class channel_manage
{
public:
    channel_manage()
    {
    }
    ~channel_manage()
    {
    }

public:
    void _insert(int wfd, int pid)
    {
        channels.emplace_back(wfd, pid);
    }

    channel &select()
    {
        std::cout << "enter select..." << std::endl;
        auto &ret = channels[next++];
        std::cout << std::endl;
        next %= channels.size();
        return ret;
    }

private:
    std::vector<channel> channels;
    int next = 0;
};

const int NUM = 10;
class channel_pool
{
public:
    channel_pool()
        : processNum(NUM)
    {
    }
    ~channel_pool()
    {
    }

public:
    void work(int rfd)
    {
        std::cout<<"enter work..."<<std::endl;
        while (true)
        {
            int cmdcode = 0;
            int n = read(0, &cmdcode, sizeof(int));
            std::cout<<"read-n:"<<n<<std::endl;
            if (n == sizeof(int))
            {
                std::cout << "slaver get a command: " << getpid() << " comdcode:" << cmdcode << std::endl;
                std::cout<<"tasks size:"<<tasks.size()<<std::endl;
                if (cmdcode >= 0 && cmdcode < tasks.size())
                {
                    tasks[cmdcode]();
                    std::cout<<"tasks done..."<<std::endl;
                }
            }
            if (n == 0)
                break;
        }
    }

    void Init()
    {
        for (int i = 0; i < processNum; i++)
        {
            int pipefd[2];
            int n = pipe(pipefd);
            if (n < 0)
            {
                perror("pipe");
                return;
            }
            pid_t id = fork();
            if (id < 0)
            {
                perror("fork");
            }
            else if (id == 0) // child
            {
                std::cout << "i am chile..." << std::endl;
                close(pipefd[1]);
                dup2(pipefd[0],0);
                work(pipefd[0]);
                std::cout << "work done..." << std::endl;
                close(pipefd[0]);
                exit(0);
            }
            else // father
            {
                close(pipefd[0]);
                _cm._insert(pipefd[1], id);
                std::cout << "_cm._insert done..." << std::endl;
            }
        }
    }

    void send(int cmdcode)
    {
        std::cout << "enter send.." << std::endl;
        auto &c = _cm.select();
        c.send(cmdcode);
    }
    // void Print()
    // {
    //     std::cout<<
    // }

    // channel&select()
    // {

    // }
private:
    // std::vector<task_t> tasks;
    channel_manage _cm;
    int processNum;
};
int main()
{
    
    LoadTask(&tasks);
    srand(time(nullptr));
    channel_pool cp;
    cp.Init();
    std::cout << "Init done." << std::endl;
    while (1)
    {
        int cmdcode = rand() % 10;
        cp.send(cmdcode);
        std::cout << "send one  done." << std::endl;

        sleep(1);
    }
    return 0;
}